home *** CD-ROM | disk | FTP | other *** search
- /*==========================================================================
- *
- * Copyright (C) 1996 Microsoft Corporation. All Rights Reserved.
- *
- * File: dplaunch.c
- * Content: Implementation of a DirectPlay launching utility
- *
- ***************************************************************************/
-
- #define INITGUID
- #define WIN32_LEAN_AND_MEAN
-
- #include <windows.h>
- #include <windowsx.h>
- #include <objbase.h>
- #include <cguid.h>
-
- #include "dplay.h"
- #include "dplobby.h"
-
- #include "resource.h"
-
- // maximum size of a string name
- #define NAMEMAX 200
-
- // service provider information
- typedef struct {
- GUID guidServiceProvider; // guid of service provider
- GUID guidAddressType; // address type required by service provider
- } SPINFO, *LPSPINFO;
-
- typedef struct {
- HWND hWnd;
- LPDIRECTPLAYLOBBYA lpDPLobbyA;
- } ENUMINFO, *LPENUMINFO;
-
- // GUID for sessions this application creates
- // {D559FC00-DC12-11cf-9C4E-00A0C905425E}
- DEFINE_GUID(MY_SESSION_GUID,
- 0xd559fc00, 0xdc12, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
-
- // prototypes
- BOOL CALLBACK LauncherWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- HRESULT InitializeLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA *lplpDPlayLobby);
- void DestroyLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby);
- void LaunchDirectPlayApplication(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby);
-
-
- // ---------------------------------------------------------------------------
- // WinMain
- // ---------------------------------------------------------------------------
- // Description: Main windows entry point.
- // Arguments:
- // HINSTANCE [in] Standard windows stuff
- // HINSTANCE [in]
- // LPSTR [in]
- // int [in]
- // Returns:
- // int
- int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
- {
- return DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_LAUNCHERDIALOG), NULL, LauncherWndProc, (LPARAM) hInstance);
- }
-
-
- // ---------------------------------------------------------------------------
- // LauncherWndProc
- // ---------------------------------------------------------------------------
- // Description: Message callback function for Launcher dialog.
- // Arguments:
- // HWND [in] Dialog window handle.
- // UINT [in] Window message identifier.
- // WPARAM [in] Depends on message.
- // LPARAM [in] Depends on message.
- // Returns:
- // BOOL TRUE if message was processed internally.
- BOOL CALLBACK LauncherWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- static HINSTANCE hInst;
- static LPDIRECTPLAYLOBBYA lpDPlayLobby;
- HRESULT hr;
-
- switch(uMsg)
- {
- case WM_INITDIALOG:
- // Save the instance handle
- hInst = (HINSTANCE)lParam;
-
- // Initialize dialog with launcher information
- lpDPlayLobby = NULL;
- hr = InitializeLauncherWindow(hWnd, &lpDPlayLobby);
- break;
-
- case WM_DESTROY:
- // Destroy launcher information in dialog
- DestroyLauncherWindow(hWnd, lpDPlayLobby);
-
- // Return failure
- EndDialog(hWnd, FALSE);
-
- break;
-
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case IDC_RUNAPPBUTTON:
- // get settings and launch application
- LaunchDirectPlayApplication(hWnd, lpDPlayLobby);
-
- break;
-
- case IDCANCEL:
- // Return failure
- EndDialog(hWnd, TRUE);
-
- break;
- }
-
- break;
- }
-
- // Allow for default processing
- return FALSE;
- }
-
- // ---------------------------------------------------------------------------
- // EnumApp
- // ---------------------------------------------------------------------------
- // Description: Enumeration callback called by DirectPlay.
- // Enumerates the applications registered with DirectPlay.
- // Arguments:
- // LPDPLAPPINFO [in] information about the application
- // LPVOID [in] user-defined context
- // DWORD [in] flags
- // Returns:
- // BOOL TRUE to continue enumerating
- BOOL FAR PASCAL EnumApp(LPCDPLAPPINFO lpAppInfo, LPVOID lpContext, DWORD dwFlags)
- {
- HWND hWnd = lpContext;
- LRESULT iIndex;
- LPGUID lpGuid;
-
- // store application name in combo box
- iIndex = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_ADDSTRING, 0, (LPARAM) lpAppInfo->lpszAppNameA);
- if (iIndex == LB_ERR)
- goto Failure;
-
- // make space for application GUID
- lpGuid = (LPGUID) GlobalAllocPtr(GHND, sizeof(GUID));
- if (lpGuid == NULL)
- goto Failure;
-
- // store pointer to GUID in combo box
- *lpGuid = lpAppInfo->guidApplication;
- SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpGuid);
-
- Failure:
- return (TRUE);
- }
-
- // ---------------------------------------------------------------------------
- // EnumAddressType
- // ---------------------------------------------------------------------------
- // Description: Enumeration callback called by DirectPlayLobby.
- // Enumerates the address types supported by the
- // given Service Provider.
- // Arguments:
- // REFGUID [in] GUID of the address type
- // LPVOID [in] user-defined context
- // DWORD [in] flags
- // Returns:
- // BOOL FALSE to stop enumerating after the first callback
- BOOL FAR PASCAL EnumAddressType(REFGUID guidAddressType, LPVOID lpContext,
- DWORD dwFlags)
- {
- LPGUID lpguidAddr = (LPGUID)lpContext;
-
-
- // Save the address type guid in the pointer
- *lpguidAddr = *guidAddressType;
-
- // Note: It is possible that some Service Providers will contain more
- // than one address type. We are only using the first address type
- // returned in this sample. A good application should save all
- // address types.
- return FALSE;
- }
-
-
- // ---------------------------------------------------------------------------
- // EnumSP
- // ---------------------------------------------------------------------------
- // Description: Enumeration callback called by DirectPlay.
- // Enumerates service providers registered with DirectPlay.
- // Arguments:
- // LPGUID [in] GUID of service provider
- // LPTSTR [in] name of service provider
- // DWORD [in] major version of DirectPlay
- // DWORD [in] minor version of DirectPlay
- // LPVOID [in] user-defined context
- // Returns:
- // BOOL TRUE to continue enumerating
- BOOL FAR PASCAL EnumSP(LPGUID lpGuid, LPTSTR lptszDesc, DWORD dwMajorVersion,
- DWORD dwMinorVersion, LPVOID lpContext)
- {
- LPENUMINFO lpEnumInfo = (LPENUMINFO)lpContext;
- LPDIRECTPLAYLOBBYA lpDPLobbyA = lpEnumInfo->lpDPLobbyA;
- HWND hWnd = lpEnumInfo->hWnd;
- HRESULT hr;
- LRESULT iIndex;
- LPSPINFO lpSPInfo;
-
- // store service provider name in combo box
- iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_ADDSTRING, 0, (LPARAM) lptszDesc);
- if (iIndex == LB_ERR)
- goto Failure;
-
- // make space for service provider info
- lpSPInfo = (LPSPINFO) GlobalAllocPtr(GHND, sizeof(SPINFO));
- if (lpSPInfo == NULL)
- goto Failure;
-
- // Initialize the guid to GUID_NULL in case it has no address types
- memset(lpSPInfo, 0, sizeof(SPINFO));
-
- // store service provider GUID and address type in combo box
- lpSPInfo->guidServiceProvider = *lpGuid;
-
- // Get the address type for the Service Provider
- hr = lpDPLobbyA->lpVtbl->EnumAddressTypes(lpDPLobbyA,
- (LPDPLENUMADDRESSTYPESCALLBACK)EnumAddressType,
- lpGuid, &lpSPInfo->guidAddressType, 0L);
-
- SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpSPInfo);
-
- Failure:
- return (TRUE);
- }
-
- // ---------------------------------------------------------------------------
- // InitializeLauncherWindow
- // ---------------------------------------------------------------------------
- // Description: Initializes the window for the Launcher.
- // Arguments:
- // HWND [in] Window handle.
- // LPDIRECTPLAYLOBBYA [out] IDirectPlayLobby interface.
- // Returns:
- // HRESULT any errors initializing the window
- HRESULT InitializeLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA *lplpDPlayLobby)
- {
- LPDIRECTPLAYLOBBYA lpDPlayLobbyA = NULL;
- ENUMINFO EnumInfo;
- HRESULT hr;
-
- // get a ANSI DirectPlay lobby interface
- hr = DirectPlayLobbyCreate(NULL, &lpDPlayLobbyA, NULL, NULL, 0);
- if FAILED(hr)
- goto Failure;
-
- // put all the DirectPlay applications in a combo box
- lpDPlayLobbyA->lpVtbl->EnumLocalApplications(lpDPlayLobbyA, EnumApp, hWnd, 0);
-
- // setup the EnumInfo structure
- EnumInfo.hWnd = hWnd;
- EnumInfo.lpDPLobbyA = lpDPlayLobbyA;
-
- // put all the service providers in a combo box
- DirectPlayEnumerate(EnumSP, &EnumInfo);
-
- // initialize the controls
- SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_SETCURSEL, (WPARAM) 0, 0);
- SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETCURSEL, (WPARAM) 0, 0);
- SendDlgItemMessage(hWnd, IDC_HOSTRADIO, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
-
- // return the ANSI lobby interface
- *lplpDPlayLobby = lpDPlayLobbyA;
-
- return (DP_OK);
-
- Failure:
-
- return (hr);
- }
-
- // ---------------------------------------------------------------------------
- // DestroyLauncherWindow
- // ---------------------------------------------------------------------------
- // Description: Destroys the launcher window.
- // Arguments:
- // HWND [in] Window handle.
- // LPDIRECTPLAYLOBBYA [in] DirectPlay Lobby interface to destroy
- // Returns:
- // Nothing
- void DestroyLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby)
- {
- WPARAM index;
- LRESULT lpData;
-
- // destroy the GUID's stored with each app name
- index = 0;
- while (TRUE)
- {
- lpData = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETITEMDATA, (WPARAM) index, 0);
- if ((lpData == CB_ERR) || (lpData == 0))
- break;
-
- GlobalFreePtr((LPVOID) lpData);
- index += 1;
- }
-
- // destroy the GUID's stored with each service provider name
- index = 0;
- while (TRUE)
- {
- lpData = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA, (WPARAM) index, 0);
- if ((lpData == CB_ERR) || (lpData == 0))
- break;
-
- GlobalFreePtr((LPVOID) lpData);
- index += 1;
- }
-
- // release the lobby interface
- if (lpDPlayLobby)
- lpDPlayLobby->lpVtbl->Release(lpDPlayLobby);
- }
-
- // ---------------------------------------------------------------------------
- // CreateAddress
- // ---------------------------------------------------------------------------
- // Description: Wrapper for the IDirectPlayLobby::CreateAddress() method.
- // Arguments:
- // LPDIRECTPLAYLOBBYA [in] DirectPlay Lobby interface to use
- // LPGUID [in] GUID of servicer provider to create address for
- // LPGUID [in] GUID of address data type
- // LPSTR [in] string to use as address data
- // LPVOID* [out] pointer to return address in
- // LPDWORD [out] pointer to return address size in
- // Returns:
- // HRESULT any error creating the address
- HRESULT CreateAddress(LPDIRECTPLAYLOBBYA lpDPlayLobby,
- LPGUID lpguidServiceProvider,
- LPGUID lpguidAddressType, LPSTR lpszAddressText,
- LPVOID *lplpAddress, LPDWORD lpdwAddressSize)
- {
- LPVOID lpAddress = NULL;
- DWORD dwAddressSize = 0;
- HRESULT hr;
-
- // check for invalid address types
- if (IsEqualGUID(lpguidAddressType, &GUID_NULL))
- return (DPERR_INVALIDPARAM);
-
- // see how much room is needed to store this address
- hr = lpDPlayLobby->lpVtbl->CreateAddress(lpDPlayLobby, lpguidServiceProvider,
- lpguidAddressType, lpszAddressText, strlen(lpszAddressText) + 1,
- NULL, &dwAddressSize);
- if (hr != DPERR_BUFFERTOOSMALL)
- goto Failure;
-
- // allocate space
- lpAddress = GlobalAllocPtr(GHND, dwAddressSize);
- if (lpAddress == NULL)
- {
- hr = DPERR_NOMEMORY;
- goto Failure;
- }
-
- // create the address
- hr = lpDPlayLobby->lpVtbl->CreateAddress(lpDPlayLobby, lpguidServiceProvider,
- lpguidAddressType, lpszAddressText, strlen(lpszAddressText) + 1,
- lpAddress, &dwAddressSize);
- if FAILED(hr)
- goto Failure;
-
- // return the address info
- *lplpAddress = lpAddress;
- *lpdwAddressSize = dwAddressSize;
-
- return (DP_OK);
-
- Failure:
- if (lpAddress)
- GlobalFreePtr(lpAddress);
-
- return (hr);
- }
-
- // ---------------------------------------------------------------------------
- // RunApplication
- // ---------------------------------------------------------------------------
- // Description: Wrapper for the IDirectPlayLobby::RunApplication() method.
- // Arguments:
- // LPDIRECTPLAYLOBBYA [in] DirectPlay Lobby interface to use
- // LPGUID [in] GUID of application to launch
- // LPGUID [in] GUID of session to host with
- // LPSTR [in] GUID of service provider to connect with
- // LPVOID [in] service-provider address to connect to
- // DWORD [in] length of address
- // LPSTR [in] name of session to host
- // LPSTR [in] name of our player
- // BOOL [in] TRUE to host session, FALSE to join
- // Returns:
- // HRESULT any error running the application
- HRESULT RunApplication(LPDIRECTPLAYLOBBYA lpDPlayLobby,
- LPGUID lpguidApplication,
- LPGUID lpguidInstance,
- LPGUID lpguidServiceProvider,
- LPVOID lpAddress,
- DWORD dwAddressSize,
- LPSTR lpszSessionName,
- LPSTR lpszPlayerName,
- BOOL bHostSession)
- {
- DWORD appID;
- DPSESSIONDESC2 sessionInfo;
- DPNAME playerName;
- DPLCONNECTION connectInfo;
- HRESULT hr;
-
- if (lpDPlayLobby == NULL)
- return (DPERR_NOINTERFACE);
-
- // fill out session description
- ZeroMemory(&sessionInfo, sizeof(DPSESSIONDESC2));
- sessionInfo.dwSize = sizeof(DPSESSIONDESC2); // Size of structure
- sessionInfo.dwFlags = 0; // DPSESSION_xxx flags
- sessionInfo.guidInstance = *lpguidInstance; // ID for the session instance
- sessionInfo.guidApplication = *lpguidApplication;// GUID of the DirectPlay application.
- sessionInfo.dwMaxPlayers = 0; // Maximum # players allowed in session
- sessionInfo.dwCurrentPlayers = 0; // Current # players in session (read only)
- sessionInfo.lpszSessionNameA = lpszSessionName; // ANSI name of the session
- sessionInfo.lpszPasswordA = NULL; // ANSI password of the session (optional)
- sessionInfo.dwReserved1 = 0; // Reserved for future MS use.
- sessionInfo.dwReserved2 = 0;
- sessionInfo.dwUser1 = 0; // For use by the application
- sessionInfo.dwUser2 = 0;
- sessionInfo.dwUser3 = 0;
- sessionInfo.dwUser4 = 0;
-
- // fill out player name
- ZeroMemory(&playerName, sizeof(DPNAME));
- playerName.dwSize = sizeof(DPNAME); // Size of structure
- playerName.dwFlags = 0; // Not used. Must be zero.
- playerName.lpszShortNameA = lpszPlayerName; // ANSI short or friendly name
- playerName.lpszLongNameA = lpszPlayerName; // ANSI long or formal name
-
- // fill out connection description
- ZeroMemory(&connectInfo, sizeof(DPLCONNECTION));
- connectInfo.dwSize = sizeof(DPLCONNECTION); // Size of this structure
- if (bHostSession)
- connectInfo.dwFlags = DPLCONNECTION_CREATESESSION; // Create a new session
- else
- connectInfo.dwFlags = DPLCONNECTION_JOINSESSION; // Join existing session
- connectInfo.lpSessionDesc = &sessionInfo; // Pointer to session desc to use on connect
- connectInfo.lpPlayerName = &playerName; // Pointer to Player name structure
- connectInfo.guidSP = *lpguidServiceProvider; // GUID of the DPlay SP to use
- connectInfo.lpAddress = lpAddress; // Address for service provider
- connectInfo.dwAddressSize = dwAddressSize; // Size of address data
-
- // launch and connect the game
- hr = lpDPlayLobby->lpVtbl->RunApplication(lpDPlayLobby,
- 0, // Flags
- &appID, // App ID
- &connectInfo, // Connection data
- NULL); // Connect event
- return (hr);
- }
-
- // ---------------------------------------------------------------------------
- // LaunchDirectPlayApplication
- // ---------------------------------------------------------------------------
- // Description: Gathers information from the dialog and runs the application.
- // Arguments:
- // HWND [in] Window handle.
- // LPDIRECTPLAYLOBBYA [in] DirectPlay Lobby interface to use
- // Returns:
- // Nothing
- void LaunchDirectPlayApplication(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby)
- {
- GUID guidApplication, guidSession, guidServiceProvider, guidAddressType;
- LPSTR lpPlayerName, lpSessionName;
- LPVOID lpAddress = NULL;
- DWORD dwAddressSize;
- LPSPINFO lpSPInfo;
- char strPlayerName[NAMEMAX], strSessionName[NAMEMAX], strAddressText[NAMEMAX];
- LRESULT iApp, iSP, iHost;
- HRESULT hr;
-
- SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launching...");
-
- // get guid of application to launch
- iApp = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETCURSEL, (WPARAM) 0, 0);
- if (iApp == CB_ERR)
- goto Failure;
-
- iApp = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETITEMDATA, (WPARAM) iApp, 0);
- if ((iApp == CB_ERR) || (iApp == 0))
- goto Failure;
-
- guidApplication = *((LPGUID) iApp);
-
- // get info for service provider to use for the connection
- iSP = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETCURSEL, (WPARAM) 0, 0);
- if (iSP == CB_ERR)
- goto Failure;
-
- iSP = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA, (WPARAM) iSP, 0);
- if ((iSP == CB_ERR) || (iSP == 0))
- goto Failure;
-
- lpSPInfo = (LPSPINFO) iSP;
- guidServiceProvider = lpSPInfo->guidServiceProvider; // GUID of service provider
- guidAddressType = lpSPInfo->guidAddressType; // address type required by service provider
-
- // get guid of session to create.
- guidSession = MY_SESSION_GUID;
-
- // get name of our player
- GetDlgItemText(hWnd, IDC_PLAYEREDIT, strPlayerName, NAMEMAX);
- lpPlayerName = strPlayerName;
-
- // get host vs. join flag
- iHost = SendDlgItemMessage(hWnd, IDC_HOSTRADIO, BM_GETCHECK, (WPARAM) 0, 0);
- if (iHost == BST_CHECKED)
- {
- iHost = TRUE; // we are hosting a session
- lpAddress = NULL; // don't need an address to host
- dwAddressSize = 0;
-
- // get name of session
- GetDlgItemText(hWnd, IDC_SESSIONEDIT, strSessionName, NAMEMAX);
- lpSessionName = strSessionName;
- }
- else
- {
- iHost = FALSE; // we are joining an existing session
- lpSessionName = NULL; // don't need a session name if we are joining
-
- lpAddress = NULL; // assume we don't need address data
- dwAddressSize = 0;
-
- // the service provider supports address data
- if (!IsEqualGUID(&guidAddressType, &GUID_NULL))
- {
- // get service-provider specific address data as a string
- GetDlgItemText(hWnd, IDC_ADDRESSEDIT, strAddressText, NAMEMAX);
-
- // convert string to a DirectPlay address
- hr = CreateAddress(lpDPlayLobby, &guidServiceProvider,
- &guidAddressType, strAddressText,
- &lpAddress, &dwAddressSize);
- }
- }
-
- // launch the application
- hr = RunApplication(lpDPlayLobby,
- &guidApplication,
- &guidSession,
- &guidServiceProvider,
- lpAddress, dwAddressSize,
- lpSessionName, lpPlayerName,
- iHost);
- if FAILED(hr)
- goto Failure;
-
- SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launch successful");
-
- if (lpAddress)
- GlobalFreePtr(lpAddress);
- return;
-
- Failure:
- if (lpAddress)
- GlobalFreePtr(lpAddress);
-
- SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launch failed");
-
- return;
- }
-
-